<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>Payment Intent API · tipsi-stripe</title>
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content="Docusaurus" />
    <meta
      name="description"
      content='&lt;h2&gt;&lt;a class="anchor" aria-hidden="true" id="introduction"&gt;&lt;/a&gt;&lt;a href="#introduction" aria-hidden="true" class="hash-link"&gt;&lt;svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"&gt;&lt;path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Introduction&lt;/h2&gt;
'
    />
    <meta name="docsearch:language" content="en" />
    <meta property="og:title" content="Payment Intent API · tipsi-stripe" />
    <meta property="og:type" content="website" />
    <meta property="og:url" content="https://tipsi.github.io/tipsi-stripe/index.html" />
    <meta
      property="og:description"
      content='&lt;h2&gt;&lt;a class="anchor" aria-hidden="true" id="introduction"&gt;&lt;/a&gt;&lt;a href="#introduction" aria-hidden="true" class="hash-link"&gt;&lt;svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"&gt;&lt;path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Introduction&lt;/h2&gt;
'
    />
    <meta name="twitter:card" content="summary" />
    <link rel="shortcut icon" href="/tipsi-stripe/img/favicon.png" />
    <link
      rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"
    />
    <link
      rel="alternate"
      type="application/atom+xml"
      href="https://tipsi.github.io/tipsi-stripe/blog/atom.xml"
      title="tipsi-stripe Blog ATOM Feed"
    />
    <link
      rel="alternate"
      type="application/rss+xml"
      href="https://tipsi.github.io/tipsi-stripe/blog/feed.xml"
      title="tipsi-stripe Blog RSS Feed"
    />
    <script type="text/javascript" src="https://buttons.github.io/buttons.js"></script>
    <script src="/tipsi-stripe/js/scrollSpy.js"></script>
    <link rel="stylesheet" href="/tipsi-stripe/css/main.css" />
    <script src="/tipsi-stripe/js/codetabs.js"></script>
  </head>
  <body class="sideNavVisible">
    <div class="fixedHeaderContainer">
      <div class="headerWrapper wrapper">
        <header>
          <a href="/tipsi-stripe/"
            ><img class="logo" src="/tipsi-stripe/img/favicon.png" alt="tipsi-stripe" />
            <h2 class="headerTitleWithLogo">tipsi-stripe</h2></a
          >
          <div class="navigationWrapper navigationSlider">
            <nav class="slidingNav">
              <ul class="nav-site nav-site-internal">
                <li class="siteNavGroupActive">
                  <a href="/tipsi-stripe/docs/index.html" target="_self">Docs</a>
                </li>
                <li class=""><a href="/tipsi-stripe/blog/" target="_self">Blog</a></li>
              </ul>
            </nav>
          </div>
        </header>
      </div>
    </div>
    <div class="navPusher">
      <div class="docMainWrapper wrapper">
        <div class="container docsNavContainer" id="docsNav">
          <nav class="toc">
            <div class="toggleNav">
              <section class="navWrapper wrapper">
                <div class="navBreadcrumb wrapper">
                  <div class="navToggle" id="navToggler">
                    <div class="hamburger-menu">
                      <div class="line1"></div>
                      <div class="line2"></div>
                      <div class="line3"></div>
                    </div>
                  </div>
                  <h2><i>›</i><span>Overview</span></h2>
                </div>
                <div class="navGroups">
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Overview</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/index.html">Start here</a>
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/compatibility.html"
                          >Compatibility</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/installation.html"
                          >Installation</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/linking.html">Linking</a>
                      </li>
                      <li class="navListItem">
                        <a
                          class="navItem"
                          href="/tipsi-stripe/docs/running-apple-pay-on-a-real-device.html"
                          >Running  Pay on a real Device</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/google-pay.html">Google Pay</a>
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/usage.html">Usage</a>
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/example.html">Example</a>
                      </li>
                      <li class="navListItem navListItemActive">
                        <a class="navItem" href="/tipsi-stripe/docs/paymentIntents.html"
                          >Payment Intent API</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/createCardOrSubscription.html"
                          >Save Card/Subscription</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/migrationIssues.html"
                          >Migration</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/changelog.html">Changelog</a>
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Objects</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/token.html">Token</a>
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/source.html">Source</a>
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/paymentMethod.html"
                          >Payment Method</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Native Pay -  &amp; G</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/canMakeNativePayPayments.html"
                          >.canMakeNativePayPayments()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/deviceSupportsNativePay.html"
                          >.deviceSupportsNativePay()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a
                          class="navItem"
                          href="/tipsi-stripe/docs/potentiallyAvailableNativePayNetworks.html"
                          >.potentiallyAvailableNativePayNetworks()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/completeNativePayRequest.html"
                          >.completeNativePayRequest()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/cancelNativePayRequest.html"
                          >.cancelNativePayRequest()</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Card Form</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/paymentrequestwithcardform.html"
                          >.paymentRequestWithCardForm()</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Card Params Object</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/createtokenwithcard.html"
                          >.createTokenWithCard()</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Bank Account Params Object</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/createtokenwithbankaccount.html"
                          >.createTokenWithBankAccount()</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Create Source Object With Params</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a
                          class="navItem"
                          href="/tipsi-stripe/docs/createsourcewithparamsparams.html"
                          >.createSourceWithParams()</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Components</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/paymentcardtextfield.html"
                          >&lt;PaymentCardTextField /&gt;</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Error Codes</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/errorcodes.html">Error Codes</a>
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Tests</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/tests-local-ci.html"
                          >Local CI</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/tests-manual.html">Manual</a>
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Troubleshooting</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/troubleshooting-android.html"
                          >Android</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/troubleshooting-jest.html"
                          >Jest</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/troubleshooting-tests.html"
                          >Tests</a
                        >
                      </li>
                      <li class="navListItem">
                        <a
                          class="navItem"
                          href="/tipsi-stripe/docs/troubleshooting-useframeworks-issue.html"
                          >use_frameworks issue</a
                        >
                      </li>
                    </ul>
                  </div>
                  <div class="navGroup">
                    <h3 class="navGroupCategoryTitle">Deprecated Docs</h3>
                    <ul class="">
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/openapplepaysetup.html"
                          >.openApplePaySetup()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/deviceSupportsApplePay.html"
                          >.deviceSupportsApplePay()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/devicesupportsandroidpay.html"
                          >.deviceSupportsAndroidPay()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/canmakeandroidpaypayments.html"
                          >.canMakeAndroidPayPayments()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a
                          class="navItem"
                          href="/tipsi-stripe/docs/canmakeapplepaypaymentsoptions.html"
                          >.canMakeApplePayPayments()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a
                          class="navItem"
                          href="/tipsi-stripe/docs/paymentrequestwithandroidpay.html"
                          >.paymentRequestWithAndroidPay()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a
                          class="navItem"
                          href="/tipsi-stripe/docs/paymentrequestwithapplepayitemsoptions.html"
                          >.paymentRequestWithApplePay()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/completeapplepayrequest.html"
                          >.completeApplePayRequest()</a
                        >
                      </li>
                      <li class="navListItem">
                        <a class="navItem" href="/tipsi-stripe/docs/cancelapplepayrequest.html"
                          >.cancelApplePayRequest()</a
                        >
                      </li>
                    </ul>
                  </div>
                </div>
              </section>
            </div>
            <script>
              var coll = document.getElementsByClassName('collapsible');
              var checkActiveCategory = true;
              for (var i = 0; i < coll.length; i++) {
                var links = coll[i].nextElementSibling.getElementsByTagName('*');
                if (checkActiveCategory) {
                  for (var j = 0; j < links.length; j++) {
                    if (links[j].classList.contains('navListItemActive')) {
                      coll[i].nextElementSibling.classList.toggle('hide');
                      coll[i].childNodes[1].classList.toggle('rotate');
                      checkActiveCategory = false;
                      break;
                    }
                  }
                }

                coll[i].addEventListener('click', function() {
                  var arrow = this.childNodes[1];
                  arrow.classList.toggle('rotate');
                  var content = this.nextElementSibling;
                  content.classList.toggle('hide');
                });
              }

              document.addEventListener('DOMContentLoaded', function() {
                createToggler('#navToggler', '#docsNav', 'docsSliderActive');
                createToggler('#tocToggler', 'body', 'tocActive');

                var headings = document.querySelector('.toc-headings');
                headings &&
                  headings.addEventListener(
                    'click',
                    function(event) {
                      var el = event.target;
                      while (el !== headings) {
                        if (el.tagName === 'A') {
                          document.body.classList.remove('tocActive');
                          break;
                        } else {
                          el = el.parentNode;
                        }
                      }
                    },
                    false
                  );

                function createToggler(togglerSelector, targetSelector, className) {
                  var toggler = document.querySelector(togglerSelector);
                  var target = document.querySelector(targetSelector);

                  if (!toggler) {
                    return;
                  }

                  toggler.onclick = function(event) {
                    event.preventDefault();

                    target.classList.toggle(className);
                  };
                }
              });
            </script>
          </nav>
        </div>
        <div class="container mainContainer">
          <div class="wrapper">
            <div class="post">
              <header class="postHeader">
                <h1 class="postHeaderTitle">Payment Intent API</h1>
              </header>
              <article>
                <div>
                  <span
                    ><h2>
                      <a class="anchor" aria-hidden="true" id="introduction"></a
                      ><a href="#introduction" aria-hidden="true" class="hash-link"
                        ><svg
                          class="hash-link-icon"
                          aria-hidden="true"
                          height="16"
                          version="1.1"
                          viewBox="0 0 16 16"
                          width="16"
                        >
                          <path
                            fill-rule="evenodd"
                            d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"
                          ></path></svg></a
                      >Introduction
                    </h2>
                    <p>Card payments with Stripe should be performed with PaymentIntents.</p>
                    <p>
                      This API was created to handle modern payments, where the cardholder's bank
                      may require the user to authenticate themselves with the bank before a payment
                      can be authorized.
                    </p>
                    <p>
                      Authentication requirements first started to appear with European banks
                      regulated by PSD2 which introduced
                      <a href="https://stripe.com/en-ca/guides/strong-customer-authentication"
                        >Strong Customer Authentication (SCA)</a
                      >
                      requirements.
                    </p>
                    <hr />
                    <p>
                      <strong>tipsi-stripe</strong> helps to support key parts of the payment
                      experience, with sections on each below.
                    </p>
                    <ol>
                      <li>
                        Creating a PaymentMethod (with card data, a card token, or a token from
                        Google Pay / Apple Pay)
                      </li>
                      <li>Initiating a payment from the mobile app</li>
                      <li>
                        Asking the user to authenticate a transaction that was attempted off-session
                        by you, the Merchant
                      </li>
                      <li>Saving a card for future use</li>
                    </ol>
                    <hr />
                    <h2>
                      <a class="anchor" aria-hidden="true" id="creating-a-paymentmethod"></a
                      ><a href="#creating-a-paymentmethod" aria-hidden="true" class="hash-link"
                        ><svg
                          class="hash-link-icon"
                          aria-hidden="true"
                          height="16"
                          version="1.1"
                          viewBox="0 0 16 16"
                          width="16"
                        >
                          <path
                            fill-rule="evenodd"
                            d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"
                          ></path></svg></a
                      >Creating a PaymentMethod
                    </h2>
                    <p>Creating a payment method using card details:</p>
                    <pre><code class="hljs css language-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> paymentMethod = <span class="hljs-keyword">await</span> stripe.createPaymentMethod({
    <span class="hljs-attr">card</span> : {
      <span class="hljs-attr">number</span> : <span class="hljs-string">'4000002500003155'</span>,
      <span class="hljs-attr">cvc</span> : <span class="hljs-string">'123'</span>,
      <span class="hljs-attr">expMonth</span> : <span class="hljs-number">11</span>,
      <span class="hljs-attr">expYear</span> : <span class="hljs-number">2020</span>
    }
  })
} <span class="hljs-keyword">catch</span> (e) {
  <span class="hljs-comment">// Handle error</span>
}
</code></pre>
                    <p>Creating a payment method using a card token. This could be:</p>
                    <ul>
                      <li>a token from Google Pay</li>
                      <li>
                        a token returned by
                        <code>await stripe.paymentRequestWithCardForm(...)</code>
                      </li>
                      <li>
                        a token returned by <code>await stripe.createTokenWithCard(...)</code>
                      </li>
                      <li>
                        a token returned by
                        <code>await stripe.createTokenWithBankAccount(...)</code>
                      </li>
                    </ul>
                    <pre><code class="hljs css language-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> paymentMethod = <span class="hljs-keyword">await</span> stripe.createPaymentMethod({
    <span class="hljs-attr">card</span> : {
      <span class="hljs-attr">token</span> : <span class="hljs-string">'1F70U2HbHFZUJkLLGyJ26n5rWDBfofzDJmdnal0dMrcEHTvKd'</span>,
    }
  })
} <span class="hljs-keyword">catch</span> (e) {
  <span class="hljs-comment">// Handle error</span>
}
</code></pre>
                    <p>
                      Here are the PropTypes that defines the shape of what can be provided to
                      createPaymentMethod:
                    </p>
                    <pre><code class="hljs css language-js">{

  <span class="hljs-comment">// Card properties:</span>
  <span class="hljs-comment">// - As an alternative to providing card PAN info, you can also provide a Stripe token:</span>
  <span class="hljs-comment">//   https://stripe.com/docs/api/payment_methods/create#create_payment_method-card</span>
  card: PropTypes.oneOfType([
    PropTypes.shape({
      <span class="hljs-attr">cvc</span>: PropTypes.string,
      <span class="hljs-attr">expMonth</span>: PropTypes.number,
      <span class="hljs-attr">expYear</span>: PropTypes.number,
      <span class="hljs-attr">number</span>: PropTypes.string,
    }),
    PropTypes.shape({ <span class="hljs-attr">token</span>: PropTypes.string }),
  ]),
  
  <span class="hljs-comment">// You can also attach billing information to a payment method</span>
  billingDetails: PropTypes.shape({
    <span class="hljs-attr">address</span>: PropTypes.shape({
      <span class="hljs-attr">city</span>: PropTypes.string,
      <span class="hljs-attr">country</span>: PropTypes.string,
      <span class="hljs-attr">line1</span>: PropTypes.string,
      <span class="hljs-attr">line2</span>: PropTypes.string,
      <span class="hljs-attr">postalCode</span>: PropTypes.string,
      <span class="hljs-attr">state</span>: PropTypes.string,
    }),
    <span class="hljs-attr">email</span>: PropTypes.string,
    <span class="hljs-attr">name</span>: PropTypes.string,
    <span class="hljs-attr">phone</span>: PropTypes.string,
  }),
}
</code></pre>
                    <h2>
                      <a
                        class="anchor"
                        aria-hidden="true"
                        id="initiating-a-payment-from-the-mobile-app"
                      ></a
                      ><a
                        href="#initiating-a-payment-from-the-mobile-app"
                        aria-hidden="true"
                        class="hash-link"
                        ><svg
                          class="hash-link-icon"
                          aria-hidden="true"
                          height="16"
                          version="1.1"
                          viewBox="0 0 16 16"
                          width="16"
                        >
                          <path
                            fill-rule="evenodd"
                            d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"
                          ></path></svg></a
                      >Initiating a payment from the mobile app
                    </h2>
                    <p>
                      To do this, make a call from your mobile app to
                      <a href="https://stripe.com/docs/api/payment_intents/create"
                        >create a Payment Intent on your backend server</a
                      >
                    </p>
                    <ul>
                      <li>
                        If you created the payment intent with
                        <code>confirmation_method='manual'</code> then you're using a manual
                        confirmation flow, and payment intents can only be confirmed from the
                        backend using the secret key. Jump to the
                        <a href="#with-manual-confirmation"
                          ><strong>... with manual confirmation</strong></a
                        >
                        section
                      </li>
                      <li>
                        Otherwise, if you created the payment intent without specifying
                        <code>confirmation_method</code> or by setting
                        <code>confirmation_method='automatic'</code> then you are using an automatic
                        confirmation flow. In this flow, you can confirm (process) the payment
                        intent right from the mobile app, and webhooks sent by Stripe will notify
                        your backend of success. This is the preferred flow. Jump to the
                        <a href="#with-automatic-confirmation"
                          ><strong>... with automatic confirmation</strong></a
                        >
                        section
                      </li>
                    </ul>
                    <h3>
                      <a class="anchor" aria-hidden="true" id="with-manual-confirmation"></a
                      ><a href="#with-manual-confirmation" aria-hidden="true" class="hash-link"
                        ><svg
                          class="hash-link-icon"
                          aria-hidden="true"
                          height="16"
                          version="1.1"
                          viewBox="0 0 16 16"
                          width="16"
                        >
                          <path
                            fill-rule="evenodd"
                            d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"
                          ></path></svg></a
                      >... with manual confirmation
                    </h3>
                    <p>In this flow, follow these steps:</p>
                    <ul>
                      <li>
                        Obtain a PaymentMethod (either one saved to the customer or a new one as
                        described in the
                        <a href="#creating-a-paymentmethod">Creating a PaymentMethod</a> section.),
                      </li>
                      <li>
                        Create a PaymentIntent on the backend, with the provided PaymentMethod and
                        the amount.
                        <ul>
                          <li>
                            set <code>confirmation_method=manual</code> when creating the intent
                          </li>
                          <li>
                            do <strong>not</strong> specify <code>off_session=true</code>, since
                            these are steps for creating an on-session payment (a payment where the
                            user is present).
                          </li>
                        </ul>
                      </li>
                      <li>
                        Confirm the PaymentIntent on the backend. If the PaymentIntent moves to a
                        <code>succeeded</code> state, then that's it! The payment was successful.
                      </li>
                      <li>
                        If the PaymentIntent status moves to <code>requires_action</code>, then
                        return the <code>client_secret</code> of the PaymentIntent to the mobile
                        app, along with the ID of the PaymentIntent.
                      </li>
                      <li>
                        Call
                        <code
                          >await stripe.authenticatePaymentIntent({ clientSecret: &quot;...&quot;
                          })</code
                        >, passing in the client_secret. This will launch an activity where the user
                        can then authenticate the payment.
                      </li>
                      <li>
                        If the call above succeeds, then call your backend with the PaymentIntent
                        ID,
                        <a href="https://stripe.com/docs/api/payment_intents/retrieve"
                          >Retrieve the PaymentIntent</a
                        >, and then
                        <a href="https://stripe.com/docs/api/payment_intents/confirm"
                          >Confirm the PaymentIntent</a
                        >.
                      </li>
                    </ul>
                    <h3>
                      <a class="anchor" aria-hidden="true" id="with-automatic-confirmation"></a
                      ><a href="#with-automatic-confirmation" aria-hidden="true" class="hash-link"
                        ><svg
                          class="hash-link-icon"
                          aria-hidden="true"
                          height="16"
                          version="1.1"
                          viewBox="0 0 16 16"
                          width="16"
                        >
                          <path
                            fill-rule="evenodd"
                            d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"
                          ></path></svg></a
                      >... with automatic confirmation
                    </h3>
                    <p>In this flow, follow these steps:</p>
                    <ul>
                      <li>
                        Obtain a PaymentMethod (either one saved to the customer or a new one as
                        described in the
                        <a href="#creating-a-paymentmethod">Creating a PaymentMethod</a> section.),
                      </li>
                      <li>
                        Create a PaymentIntent on the backend, with the provided PaymentMethod and
                        the amount.
                        <ul>
                          <li>
                            set <code>confirmation_method=automatic</code> when creating the intent
                            (or omit it, since it is the default)
                          </li>
                          <li>
                            do <strong>not</strong> specify <code>off_session=true</code>, since
                            these are steps for creating an on-session payment (a payment where the
                            user is present).
                          </li>
                        </ul>
                      </li>
                      <li>
                        Call <code>await stripe.confirmPaymentIntent({ ... })</code>, passing in the
                        client_secret. If an authentication is needed then an activity will be
                        launched where the user can then authenticate the payment. If the user
                        authenticates, then the payment is confirmed automatically and the
                        <code>stripe.confirmPaymentIntent</code> call resolves with the result,
                        which includes the resulting status of the payment intent. The statuses in a
                        <a href="https://stripe.com/docs/payments/intents"
                          >Payment Intent Lifecycle</a
                        >
                        can be viewed through that link.
                      </li>
                      <li>
                        On your backend, you can listen for webhooks of the payment intent
                        succeeding that will be sent by Stripe.
                      </li>
                    </ul>
                    <h2>
                      <a
                        class="anchor"
                        aria-hidden="true"
                        id="you-initiated-a-payment-on-the-server-that-required-authentication-from-the-user"
                      ></a
                      ><a
                        href="#you-initiated-a-payment-on-the-server-that-required-authentication-from-the-user"
                        aria-hidden="true"
                        class="hash-link"
                        ><svg
                          class="hash-link-icon"
                          aria-hidden="true"
                          height="16"
                          version="1.1"
                          viewBox="0 0 16 16"
                          width="16"
                        >
                          <path
                            fill-rule="evenodd"
                            d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"
                          ></path></svg></a
                      >You initiated a payment on the server that required authentication from the
                      user
                    </h2>
                    <p>
                      In this scenario, you attempted to confirm a PaymentIntent on the server using
                      a payment method with <code>off_session=true</code>, however the payment
                      required authentication. The <code>/confirm</code> API call would fail and the
                      PaymentIntent would transition to <code>status=requires_payment_method</code>.
                    </p>
                    <p>
                      At this stage the user needs to be brought back on-session, via an email or
                      notification. When the user is brought into the app, you should, for the same
                      PaymentIntent:
                    </p>
                    <ol>
                      <li>
                        Present the option to attempt the payment using the same card, or to provide
                        a new one.
                      </li>
                      <li>
                        Attach the selected card to the payment method to the PaymentIntent on the
                        server side.
                      </li>
                      <li>
                        Handle the payment as though it were an on-session payment. See the section
                        <a href="#initiating-a-payment-from-the-mobile-app"
                          >Initiating a payment from the mobile app</a
                        >
                      </li>
                    </ol>
                    <h2>
                      <a
                        class="anchor"
                        aria-hidden="true"
                        id="the-user-is-saving-a-card-for-future-use"
                      ></a
                      ><a
                        href="#the-user-is-saving-a-card-for-future-use"
                        aria-hidden="true"
                        class="hash-link"
                        ><svg
                          class="hash-link-icon"
                          aria-hidden="true"
                          height="16"
                          version="1.1"
                          viewBox="0 0 16 16"
                          width="16"
                        >
                          <path
                            fill-rule="evenodd"
                            d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"
                          ></path></svg></a
                      >The user is saving a card for future use
                    </h2>
                    <p>
                      When saving a card as a PaymentMethod to either bill a user later, or for the
                      user to make purchases with, we want to collect authentication up-front, if
                      it's needed by the card, to minimize the chance that we will need to interrupt
                      them for authentication on future payments. We can prepare the card by using a
                      SetupIntent. Here are the steps:
                    </p>
                    <ol>
                      <li>
                        Create a SetupIntent on the server (use
                        <code>confirmation_method=automatic</code>) for the selected payment method.
                      </li>
                      <li>Return the <code>client_secret</code> of the SetupIntent to the app.</li>
                      <li>
                        Call <code>stripe.confirmSetupIntent()</code>. This will prompt the user for
                        authentication (if needed) and finishes the setup.
                      </li>
                    </ol>
                    <pre><code class="hljs css language-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> stripe.confirmSetupIntent({
    <span class="hljs-attr">clientSecret</span> : <span class="hljs-string">"..."</span>
  })
} <span class="hljs-keyword">catch</span> (e) {
  <span class="hljs-comment">// handle exception here</span>
}
</code></pre>
                  </span>
                </div>
              </article>
            </div>
            <div class="docs-prevnext">
              <a class="docs-prev button" href="/tipsi-stripe/docs/example.html"
                ><span class="arrow-prev">← </span><span>Example</span></a
              ><a class="docs-next button" href="/tipsi-stripe/docs/createCardOrSubscription.html"
                ><span>Save Card/Subscription</span><span class="arrow-next"> →</span></a
              >
            </div>
          </div>
        </div>
      </div>
      <footer class="nav-footer" id="footer">
        <section class="sitemap">
          <a href="/tipsi-stripe/" class="nav-home"></a>
          <div>
            <h5>Docs</h5>
            <a href="/tipsi-stripe/docs/en/index.html">Getting Started</a
            ><a href="/tipsi-stripe/docs/en/running-apple-pay-on-a-real-device.html"
              >Running on Device</a
            ><a href="/tipsi-stripe/docs/en/index.html">API Reference</a>
          </div>
          <div>
            <h5>More</h5>
            <a href="/tipsi-stripe/blog">Blog</a><a href="https://github.com/">GitHub</a
            ><a
              data-show-count="true"
              class="github-button"
              href="https://github.com/tipsi/tipsi-stripe"
              data-icon="octicon-star"
              data-count-href="/tipsi/tipsi-stripe/stargazers"
              data-count-aria-label="# stargazers on GitHub"
              aria-label="Star this project on GitHub"
              >Star</a
            >
          </div>
        </section>
        <section class="copyright">Copyright © 2019 Tipsi.</section>
      </footer>
    </div>
  </body>
</html>
